package api

import (
	"context"
	"fmt"
	"github.com/gin-gonic/gin"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
	"net/http"
	"strconv"
	"sub_web/src/forms"
	"sub_web/src/global"
	"sub_web/src/global/response"
	"sub_web/src/proto"
	utils "sub_web/src/util"
	"time"
)

func SwitchGrpcErrorToHttp(err error, c *gin.Context) {
	if err != nil {
		if e, ok := status.FromError(err); ok {
			switch e.Code() {
			case codes.NotFound:
				c.JSON(http.StatusNotFound, gin.H{
					"msg": e.Message(),
				})
			case codes.Internal:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": "内部错误",
				})
			case codes.InvalidArgument:
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": "参数错误",
				})
			case codes.AlreadyExists:
				c.JSON(http.StatusBadRequest, gin.H{
					"msg": "用户已存在",
				})
			default:
				c.JSON(http.StatusInternalServerError, gin.H{
					"msg": "未知错误",
				})
			}
		}
	}
}

func SwitchSubInfo2SubModel(subInfo *proto.SubInfo) *response.SubscribeInfo {
	startTime, _ := time.Parse("2020-02-02", subInfo.StartData)
	endTime, _ := time.Parse("2020-02-02", subInfo.EndData)
	return &response.SubscribeInfo{
		Id:        int(subInfo.Id),
		UserId:    int(subInfo.OwnerId),
		Title:     subInfo.Title,
		Describe:  subInfo.Describe,
		StartDate: &startTime,
		EndDate:   &endTime,
		Reward:    int(subInfo.Reward),
		Address:   subInfo.Address,
		Phone:     subInfo.Phone,
		Onwer: response.User{
			Id:       int(subInfo.Owner.Id),
			UserName: subInfo.Owner.UserName,
			Phone:    subInfo.Owner.Phone,
			Name:     subInfo.Owner.Name,
			Identify: subInfo.Owner.Identify,
			RoleID:   int(subInfo.Owner.RoleID),
			Password: subInfo.Owner.Password,
		},
	}
}

// rpc CreateSubscribe(SubInfo) returns(SubInfo);
// rpc GetSubList(PageInfo) returns(SubResponse);
// rpc GetSubById(SubIdRequest) returns(SubInfo);
// rpc GetSubBySubName(SubNameRequest) returns(SubResponse);
// rpc GetSubByUserId(UserIdRequest) returns(SubResponse);
// rpc UpdateSub(UpdateSubRequest) returns(google.protobuf.Empty);
// rpc DeleteSub(DeleteSubRequest) returns(google.protobuf.Empty);
func DeleteSub(ctx *gin.Context) {
	subIdstr := ctx.Query("subid")
	subId, _ := strconv.Atoi(subIdstr)
	userIdstr := ctx.Query("userid")
	userId, _ := strconv.Atoi(userIdstr)

	_, err := global.SubClient.DeleteSub(context.Background(), &proto.DeleteSubRequest{
		SubId:  int32(subId),
		UserId: int32(userId),
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, ctx)
		return
	}
	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "删除成功",
		"code": 200,
		"date": nil,
	})
}

func UpdateSub(ctx *gin.Context) {
	var sub response.SubscribeInfo
	err := ctx.ShouldBind(&sub)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, utils.ErrResp(err))
		return
	}
	_, err = global.SubClient.UpdateSub(context.Background(), &proto.UpdateSubRequest{
		SubId:     uint32(sub.Id),
		Title:     sub.Title,
		Describe:  sub.Describe,
		StartData: sub.StartDate.Format("2006-02-02"),
		EndData:   sub.EndDate.Format("2006-02-02"),
		Reward:    int32(sub.Reward),
		Address:   sub.Address,
		Phone:     sub.Phone,
	})
	if err != nil {
		SwitchGrpcErrorToHttp(err, ctx)
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "修改成功",
		"data": nil,
		"code": 200,
	})
}

func GetSubByUserId(ctx *gin.Context) {
	userIds := ctx.Query("userid")
	userId, err := strconv.Atoi(userIds)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg":  "参数错误",
			"data": nil,
			"code": 400,
		})
		return
	}
	var subList []*response.SubscribeInfo
	subInfos, err := global.SubClient.GetSubByUserId(context.Background(), &proto.UserIdRequest{UserId: int32(userId)})
	if err != nil {
		SwitchGrpcErrorToHttp(err, ctx)
		return
	}
	for _, v := range subInfos.SubInfo {
		sub := SwitchSubInfo2SubModel(v)
		subList = append(subList, sub)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"code": 200,
		"data": subList,
	})
}

func GetSubBySubName(ctx *gin.Context) {
	subName := ctx.Query("subname")
	var subList []*response.SubscribeInfo
	subInfos, err := global.SubClient.GetSubBySubName(context.Background(), &proto.SubNameRequest{Title: subName})
	if err != nil {
		SwitchGrpcErrorToHttp(err, ctx)
		return
	}
	for _, v := range subInfos.SubInfo {
		sub := SwitchSubInfo2SubModel(v)
		subList = append(subList, sub)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"code": 200,
		"data": subList,
	})
}

func GetSubById(ctx *gin.Context) {
	subIdstr := ctx.Query("subId")
	subId, err := strconv.Atoi(subIdstr)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"msg":  "参数错误",
			"data": nil,
			"code": 400,
		})
		return
	}
	subInfo, err := global.SubClient.GetSubById(context.Background(), &proto.SubIdRequest{SubId: int32(subId)})
	if err != nil {
		SwitchGrpcErrorToHttp(err, ctx)
		return
	}

	res := SwitchSubInfo2SubModel(subInfo)

	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"data": res,
		"code": 200,
	})
}

func GetSubList(ctx *gin.Context) {
	var subList []*response.SubscribeInfo
	pns := ctx.Query("pn")
	pn, err := strconv.Atoi(pns)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg":  "参数错误",
			"code": 500,
			"data": nil,
		})
		return
	}
	userIds := ctx.Query("userId")
	userId, _ := strconv.Atoi(userIds)
	res, err := global.SubClient.GetSubList(context.Background(), &proto.PageInfo{
		Pn:     int32(pn),
		Psize:  5,
		UserId: int32(userId),
	})
	if err != nil {
		fmt.Println(err)
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg":  "获取失败",
			"code": 500,
			"data": nil,
		})
		return
	}

	for _, v := range res.SubInfo {
		var sub *response.SubscribeInfo
		sub = SwitchSubInfo2SubModel(v)
		subList = append(subList, sub)
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "查询成功",
		"code": 200,
		"data": subList,
	})
}

func CreateSub(ctx *gin.Context) {
	var req forms.SubscribeReq
	err := ctx.ShouldBind(&req)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, utils.ErrResp(err))
		return
	}

	subInfo, err := global.SubClient.CreateSubscribe(context.Background(), &proto.SubInfo{
		OwnerId:   int32(req.UserId),
		Title:     req.Title,
		Describe:  req.Describe,
		Address:   req.Address,
		Reward:    int32(req.Reward),
		StartData: req.StartDate,
		EndData:   req.EndDate,
		Phone:     req.Phone,
	})
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg":  "内部错误",
			"code": 500,
			"data": nil,
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"msg":  "插入成功",
		"data": subInfo,
		"code": 200,
	})
}
